﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace CrushGame
{
    /// <summary>
    /// Base classs for all Humanoid objects in the world. Handles basic logic like
    /// rendering, physics and initializing these components
    /// </summary>
    public class Person : IPersonInterface
    {
        //Basic Variables all 'Persons' need
        Texture2D _sprite;
        Vector2 _location;
        Vector2 _velocity;
        CollisionObject2D _hitbox;

        Vector2 _accelerationRate;

        /// <summary>
        /// Location of the person
        /// </summary>
        public Vector2 Location
        {
            get { return _location; }
            set { _location = value; }
        }  
        
        /// <summary>
        /// Rate at which the person is currently accelerating or decelerating
        /// </summary>
        public Vector2 AccelerationRate
        {
            get { return _accelerationRate; }
            set { _accelerationRate = value; }
        }

        /// <summary>
        /// Sprite of the person
        /// </summary>
        public Texture2D Sprite
        {
            get { return _sprite; }
        }
        /// <summary>
        /// This is a protected mutator for children to access our sprite
        /// </summary>
        protected Texture2D ParentSprite
        {
            get { return _sprite; }
            set { _sprite = value; }
        }
        /// <summary>
        /// Velocity of the Person
        /// </summary>
        public Vector2 Velocity
        {
            get { return _velocity; }
            set { _velocity = value; }
        }
        /// <summary>
        /// Collision object
        /// </summary>
        public CollisionObject2D Hitbox
        {
            get { return _hitbox; }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        public Person()
        {
            //Nothing Yet
            _location = new Vector2(50.0f, 50.0f);
            _velocity = new Vector2(0.0f, 0.0f);
            _accelerationRate = new Vector2(0.0f, 0.0f);
        }

        /// <summary>
        /// Loads this person's sprite
        /// </summary>
        /// <param name="Content">The Content Manager to load the person's assets through</param>
        /// <param name="OverrideImage">If a non-standard sprite for this person-type is needed, specify asset name here</param>
        public virtual void ContentInitialize(ContentManager Content, string OverrideImage = "")
        {
            //Initialize our sprite here. Simple at the moment, not so much later
            if(OverrideImage != "")
            {
                _sprite = Content.Load<Texture2D>(OverrideImage);
            }
            else
            {
                _sprite = Content.Load<Texture2D>("Neutral");
            }
            _hitbox = new CollisionObject2D(this);
        }

        /// <summary>
        /// Updates the Person
        /// </summary>
        /// <param name="DeltaTime">Time elapsed since last frame</param>
        public virtual void Update(float DeltaTime)
        {
            //Physics happens here. For now that is modifying location by velocity by time
            //New Velo
            _velocity += _accelerationRate * DeltaTime;

            //New position
            _location += _velocity * DeltaTime;

            //Degrade acceleration
            _accelerationRate *= 0.65f;

            //Cap X
            if (Math.Abs(_accelerationRate.X) <= 0.001f)
            {
                _accelerationRate.X = 0.0f;
            }
            
            //Cap Y
            if (Math.Abs(_accelerationRate.Y) <= 0.001f)
            {
                _accelerationRate.Y = 0.0f;
            }

            //cut velocity if we slow too far down
            if (_accelerationRate.X == 0.0f && _accelerationRate.Y == 0.0f)
            {
                _velocity = new Vector2(0.0f, 0.0f);
            }

            _hitbox.Update();
        }

        /// <summary>
        /// Shuts down and cleans up components or connections
        /// </summary>
        public virtual void Shutdown()
        {
            //Um... Nothing yet.
        }

        
        /// <summary>
        /// Renders the person to the screen at their location
        /// </summary>
        /// <param name="Batch">The spritebatch to render with</param>
        public virtual void Draw(SpriteBatch Batch)
        {
            //Simple enough
            Batch.Draw(_sprite, _location, Color.White);
        }

    }
}
